require 'forwardable'
require 'proxy_pump/version'
require 'proxy_pump/core_ext'
require 'proxy_pump/generator'
require 'proxy_pump/configuration'
require 'proxy_pump/database'
require 'proxy_pump/cache'
require 'proxy_pump/server'
require 'proxy_pump/pump'
require 'proxy_pump/cli'
module ProxyPump

  extend self

  extend Forwardable

  def_delegators :configuration, :logger

  def configuration
    @configuration ||= Configuration.new
  end

  def configure(&block)
    tap { yield configuration }
  end

  def reset
    tap { @configuration = Configuration.new }
  end

  # Load configuration from the specified YAML file.
  # @param [String] yaml: the path of the YAML file
  #
  def load(yaml)
    self.tap do
      begin
        options = YAML.load File.read(yaml)
        @configuration = Configuration.new options
      rescue Errno::ENOENT
        logger.error 'YAML configuration file could not be found. Using defaults.'
      rescue Psych::SyntaxError
        logger.error 'YAML configuration file contains invalid syntax. Using defaults.'
      rescue => e
        logger.error e.message + e.backtrace.join('\n')
      end
    end
  end

  def cache
    @cache ||= Cache.new(configuration.redis)
  end

  def database
    @database ||= Database.new(configuration.database)
  end

  def server
    @server ||= Server.new(configuration.server)
  end

  def pump
    @pump ||= Pump.new(configuration.pump)
  end

  def application(&block)
    @application ||= API.new
    if block_given?
      @application.instance_eval(&block)
    else
      @application
    end
  end

  at_exit do
    database.shutdown
    cache.shutdown
  end

end # ProxyPump
require 'proxy_pump/routes'
